<?php

/**
 * Предоставляет интерфейс для доступа к движку кеширования
 */
class CacheController implements iCacheController {
	
	private
		$defaultLifetime,
		$engine   = null,
		$disabled = false;	
	
	private static $instance = false;
	
	/**
	 * Возвращает объект класса CacheController
	 * @return CacheController
	 */
	public static function getInstance () {
		if (self::$instance === false) {
			self::$instance = new CacheController;
		}
		return self::$instance;
	}
	
	private function __construct () {
		$regedit = Regedit::getInstance();
		
		$enabled = $regedit->get ('//settings/cache/enable');
		
		if ($enabled == 1) {		
			$this->defaultLifetime = (int) $regedit->get ('//settings/cache/default_lifetime');
			$tis->dir = ENGINE_ROOT . '/cache/';
		} else {
			$this->disabled = true;
		}
	}
	
	/**
	 * Инициализация движка кеширования
	 * @param string $engineName название движка
	 * @return void
	 */
	public function loadEngine ($engineName) {
		$engineClassFile = ENGINE_ROOT . '/classes/CacheController/backend/' . $engineName . '.php';
		if (!file_exists ($engineClassFile)) {
			throw new CoreException (lang('error_backend_engine_not_exists',__CLASS__));
		}
		
		include ENGINE_ROOT . '/classes/CacheController/backend/iCacheControllerBackend.php';
		include $engineClassFile;
		
		$className = 'cache_engine_' . $engineName;
		$this->engine = new $className;
	}
	
	/**
	 * Получить строку из кеша
	 * @param array $params массив с параметрами
	 * @return string
	 */
	public function getString (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params);
		return $this->engine->get ($params);
	}
	
	/**
	 * Получить массив из кеша
	 * @param array $params массив с параметрами
	 * @return array
	 */
	public function getArray (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params);
		return $this->engine->getArray ($params);
	}
	
	/**
	 * Получить объект из кеша
	 * @param array $params массив с параметрами
	 * @return array
	 */
	public function getObject (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params);
		return $this->engine->getObject ($params);
	}
	
	/**
	 * Записать строку в кеш
	 * @param array $params массив с параметрами
	 * @return void
	 */
	public function writeString (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params, true);
		$this->engine->set ($params);
	}
	
	/**
	 * Записать массив в кеш
	 * @param array $params массив с параметрами
	 * @return void
	 */
	public function writeArray (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params, true);
		$this->engine->setArray ($params);
	}
	
	/**
	 * Записать объект в кеш
	 * @param array $params массив с параметрами
	 * @return void
	 */
	public function writeObject (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params, true);
		$this->engine->setObject ($params);
	}
	
	/**
	 * Удалить елемент из кеша
	 * @param array $params массив с параметрами
	 * @return void
	 */
	public function delete (array $params) {
		if ($this->disabled) {
			return false;
		}
		
		$this->checkEngine ();
		$this->validate ($params);
		$this->engine->delete ($params);
	}
	
	/**
	 * Валидирует параметры кеша
	 */
	private function validate (array &$params, $needValue = false) {
		if (!isset ($params['key'])) {
			throw new CoreException (lang ('error_expected_cache_key',__CLASS__));
		}
		if ($needValue && !isset ($params['value'])) {
			throw new CoreException (lang ('error_expected_cache_value',__CLASS__));
		}
		if (!isset ($params['lifetime'])) {
			$params['lifetime'] = $this->defaultLifetime;
		}
		if (isset ($params['dir'])) {
			$params['dir'] = trim ($params['dir']) . '/';
		} else {
			$params['dir'] = '';
		}
		$params['key']      = (string) $params['key'];
		$params['lifetime'] = (int)    $params['lifetime'];
		$params['dir']      = (string) $params['dir'];
	}
	
	/**
	 * Проверка движка
	 */
	private function checkEngine () {
		if ($this->engine === null) {
			throw new CoreException (lang ('error_engine_not_loaded',__CLASS__));
		}
	}
}
